#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <android/log.h>
#include "../Str/StringOperate.h"
#include "DBConfig.h"
#include "../jsoncpp/json/json.h"
#include "../mutex/tmutex.h"

extern "C"
{
	#include "./sqlite/sqlite3.h"
};

using namespace std;

int CDBConfig::SearchTerConf(void* para,int nCount,char** column_value,char** column_name)
{
	int * pTerConf = (int *)para;

	*pTerConf = 1;
    return 0;
}

int CDBConfig::GetTerConf(void* para,int nCount,char** column_value,char** column_name)
{
	char * pTerConf = (char *)para;
	if(nCount < 1)
	{
		return -1;
	}

	for (int i = 0; i < nCount; i++)
	{
		LOGI("%s == %s\n",column_name[i], column_value[i]);
		strcpy(pTerConf,column_value[i]);
	}

    return 0;
}

CDBConfig::CDBConfig()
{
	m_pLog = new CLog;
	m_pLog->SetLogInfo(15,"/sdcard/YJ_Health/Log/","YJ_DB",200,90);

	m_pDBName = new char[255];
	memset(m_pDBName,0,255);


	IniDBConf("/sdcard/YJ_Health/DB_Local.db");
}

CDBConfig::~CDBConfig()
{
	delete m_pLog;
	delete [] m_pDBName;
	m_pDBName = NULL;
}

int CDBConfig::InitTransParam()
{
	//兼容旧版本，已经注册的设备，备份数据库设置为已注册。
	char RegisterCode[1024] = {0};
	char cSQL[1024] = {0};
	int nRet = ReadDBConfig("registerCODE", "null",RegisterCode);
	if(nRet == 0)
	{
		sprintf(cSQL,"insert into Tab_Ter_Conf VALUES('registerCODE','%s')",RegisterCode);
	}

    return 0;
}

//建立数据库，插入数据表等
int CDBConfig::IniDBConf(const char * DBName)
{
	sqlite3 * pDb = NULL;
	char cSqlStr[1024] = {0};
	char errMsg[1024] = {0};
	char * pErrMsg = errMsg;
	int ret = -1;

	//数据库打开失败
	if(SQLITE_OK != sqlite3_open(DBName, &pDb))
	{
		m_pLog->WriteLog(API_LOG_LEVEL,"IniDBConf:sqlite3_open failure");
		sqlite3_close(pDb);
		return DB_OPEN_FAILURE;
	}
	strcpy(m_pDBName,DBName);

	//创建表(终端配置)
	int nRet = sqlite3_exec(pDb,"CREATE TABLE IF NOT EXISTS Tab_Ter_Conf(ItemName varchar(100) PRIMARY KEY,ItemValue varchar(100))",NULL,NULL,&pErrMsg);
	sqlite3_free(pErrMsg);
	//创建表(交易信息)
	nRet = sqlite3_exec(pDb,"CREATE TABLE IF NOT EXISTS Tab_File_Info(FileName varchar(255) PRIMARY KEY,binData blob)",NULL,NULL,&pErrMsg);
	sqlite3_free(pErrMsg);

//    //创建表(冠字号信息)
//    nRet = sqlite3_exec(pDb,"CREATE TABLE IF NOT EXISTS Tab_SNR_Info(batchNum varchar(100),denomination  varchar(100),SNR varchar(100),UserID varchar(100),Time varchar(100) PRIMARY KEY)",NULL,NULL,&pErrMsg);
//    sqlite3_free(pErrMsg);

	sqlite3_close(pDb);
	return DB_OK;
}

//读取数据库配置
int CDBConfig::ReadDBConfig(const char * pKey, const char *  defaultValue,char * Result)
{
	sqlite3 * pDb = NULL;
	char cSqlStr[1024] = {0};
	char errMsg[1024] = {0};
	char * pErrMsg = errMsg;
	int ret = -1;
	char DBResult[4096] = {0};

	//数据库打开失败
	if(SQLITE_OK != sqlite3_open(m_pDBName, &pDb))
	{
		LOGI("ReadDBConfig:sqlite3_open failure");
		sqlite3_close(pDb);
		if(defaultValue != NULL)
			strcpy(Result,defaultValue);
		return DB_OPEN_FAILURE;
	}

	memset(cSqlStr,0,1024);
	sprintf(cSqlStr,"select ItemValue from Tab_Ter_Conf where ItemName = '%s'",pKey);
	//查询配置信息
	if( SQLITE_OK != sqlite3_exec(pDb,cSqlStr,GetTerConf,DBResult,&pErrMsg))
	{
		LOGI("select failure,errMsg :%s",pErrMsg);
		sqlite3_close(pDb);
		if(defaultValue != NULL)
			strcpy(Result,defaultValue);
		return DB_EXC_FAILURE;
	}

	if(!strlen(DBResult))
	{
		LOGI("ReadDBConfig failure,ITEM_INEXISTENCE");
		sqlite3_close(pDb);
		if(defaultValue != NULL)
			strcpy(Result,defaultValue);
		return DB_INEXISTENCE;
	}

	sqlite3_free(pErrMsg);
	strcpy(Result,DBResult);
	sqlite3_close(pDb);
	return DB_OK;
}

int CDBConfig::WriteDBConfig(const char *  pKey, const char *  pValue)
{
	sqlite3 * pDb = NULL;
	char cSqlStr[1024] = {0};
	char errMsg[1024] = {0};
	char * pErrMsg = errMsg;
	int ret = -1;
	char DBResult[1024] = {0};

	//数据库打开失败
	if(SQLITE_OK != sqlite3_open(m_pDBName, &pDb))
	{
		m_pLog->WriteLog(API_LOG_LEVEL,"WriteDBConfig:sqlite3_open failure");
		sqlite3_close(pDb);
		return DB_OPEN_FAILURE;
	}

	int nItemCount = 0;
	sprintf(cSqlStr,"SELECT * FROM Tab_Ter_Conf WHERE ItemName = '%s'",pKey);

	//写配置信息
	if(SQLITE_OK == sqlite3_exec(pDb,cSqlStr,SearchTerConf,&nItemCount,&pErrMsg))
	{
		sqlite3_free(pErrMsg);
		if(1 == nItemCount)
		{
			//存在当前配置的信息，更新值
			m_pLog->WriteLog(API_LOG_LEVEL,"update item %s=%s",pKey,pValue);
			memset(cSqlStr,0,1024);
			sprintf(cSqlStr,"UPDATE Tab_Ter_Conf SET ItemValue = '%s' WHERE ItemName = '%s'",pValue,pKey);
			if(SQLITE_OK == sqlite3_exec(pDb,cSqlStr,NULL,NULL,&pErrMsg))
			{
				sqlite3_free(pErrMsg);
				sqlite3_close(pDb);
				return DB_OK;
			}
			sqlite3_free(pErrMsg);
			sqlite3_close(pDb);
			return DB_EXC_FAILURE;
		}
		else
		{
			//不存在则插入
			m_pLog->WriteLog(API_LOG_LEVEL,"insert item %s=%s",pKey,pValue);
			memset(cSqlStr,0,1024);
			sprintf(cSqlStr,"insert into Tab_Ter_Conf VALUES('%s','%s')",pKey,pValue);
			if(SQLITE_OK == sqlite3_exec(pDb,cSqlStr,NULL,NULL,NULL))
			{
				sqlite3_close(pDb);
				return DB_OK;
			}

			sqlite3_close(pDb);
			return DB_EXC_FAILURE;
		}
	}

	m_pLog->WriteLog(API_LOG_LEVEL,"WriteDBConfig :%s",pErrMsg);
	sqlite3_close(pDb);
	sqlite3_free(pErrMsg);
	return DB_EXC_FAILURE;
}
//读写数据库文件
int CDBConfig::ReadDBFile(const char * pFileName,unsigned char * pFileValue,int *nLen)
{
	sqlite3 * pDb = NULL;
	char cSqlStr[1024] = {0};
	char errMsg[1024] = {0};
	char * pErrMsg = errMsg;
	int ret = -1;
	char DBResult[255] = {0};

	//数据库打开失败
	if(SQLITE_OK != sqlite3_open(m_pDBName, &pDb))
	{
		LOGI("WriteDBConfig:sqlite3_open failure");
		sqlite3_close(pDb);
		return DB_OPEN_FAILURE;
	}

	sqlite3_stmt* stmt = NULL;
	unsigned char *data=NULL;
	sprintf(cSqlStr,"select binData from Tab_File_Info where fileName='%s';",pFileName);
	sqlite3_prepare(pDb,cSqlStr,-1,&stmt,0);
	sqlite3_step(stmt);
	data= (unsigned char *)sqlite3_column_blob(stmt,0); 	//得到纪录中的BLOB字段
	*nLen= sqlite3_column_bytes(stmt, 0);					//得到字段中数据的长度
	memcpy(pFileValue,data,*nLen);
	sqlite3_finalize(stmt);
	sqlite3_close(pDb);

	unsigned char HexData[4096] = {0};
	ASCIIStr_HexStr(pFileValue,HexData,*nLen);
	m_pLog->WriteLog(API_LOG_LEVEL,"ReadDBFile %s-%s:%d:%s",m_pDBName,pFileName,*nLen,HexData);

	return 0;
}

int CDBConfig::WriteDBFile(const char * pFileName, unsigned char * pFileValue,int nLen)
{
	sqlite3 * pDb = NULL;
	char cSqlStr[1024] = {0};
	char errMsg[1024] = {0};
	char * pErrMsg = errMsg;
	int ret = -1;
	char DBResult[255] = {0};

	//数据库打开失败
	if(SQLITE_OK != sqlite3_open(m_pDBName, &pDb))
	{
		LOGI("WriteDBConfig:sqlite3_open failure");
		sqlite3_close(pDb);
		return DB_OPEN_FAILURE;
	}

	//是否存在，如存在的话 ，UPDATE该项
    sprintf(cSqlStr,"SELECT count(*) from Tab_File_Info WHERE FileName='%s'",pFileName);
    sqlite3_stmt* stmt = NULL;
    sqlite3_prepare(pDb, cSqlStr, -1, &stmt, NULL);
    sqlite3_step(stmt);
    int count=sqlite3_column_int(stmt,0);
    sqlite3_finalize(stmt);

    if(count > 0)
    {
    	//存在 UPDATA
    	LOGI("WriteDBConfig:项已存在,更新");
        sprintf(cSqlStr,"UPDATE Tab_File_Info SET binData = ? WHERE FileName = '%s'",pFileName);
    }
    else
    {
    	//不存在 INSERT
    	LOGI("WriteDBConfig:项不存在,插入");
    	sprintf(cSqlStr,"insert into Tab_File_Info values ('%s',?);",pFileName);
    }

	stmt = NULL;
	ret = sqlite3_prepare(pDb,cSqlStr,-1,&stmt,NULL);
	sqlite3_bind_blob(stmt,1,pFileValue,nLen,NULL);
	ret = sqlite3_step(stmt);
	sqlite3_finalize(stmt);
	sqlite3_close(pDb);

	unsigned char HexData[4096] = {0};
	ASCIIStr_HexStr(pFileValue,HexData,nLen);
	LOGI("WriteDBFile %s-%s:%d:%s",m_pDBName,pFileName,nLen,HexData);

	return 0;
}

int CDBConfig::Sqlite_ExcuteSQL(const char * strSQL)
{
	sqlite3 * pDb = NULL;
	char errMsg[1024] = {0};
	char * pErrMsg = errMsg;
	int ret = 0;
	char DBResult[255] = {0};

	m_pLog->WriteLog(API_LOG_LEVEL,"Sqlite_ExcuteSQL:%s",strSQL);
	//数据库打开失败
	if(SQLITE_OK != sqlite3_open(m_pDBName, &pDb))
	{
		m_pLog->WriteLog(API_LOG_LEVEL,"WriteDBConfig:sqlite3_open failure");
		sqlite3_close(pDb);
		return DB_OPEN_FAILURE;
	}

	//是否存在，如存在的话 ，UPDATE该项
	sqlite3_stmt* stmt = NULL;
	sqlite3_prepare(pDb, strSQL, -1, &stmt, NULL);
	int rv = sqlite3_step(stmt);
	if(SQLITE_DONE != rv)
	{
		m_pLog->WriteLog(API_LOG_LEVEL,"Sqlite_ExcuteSQL Failure,ErrorCode = %d",rv);
		ret = -1;
	}
	sqlite3_finalize(stmt);
	sqlite3_close(pDb);

    m_pLog->WriteLog(API_LOG_LEVEL,"Sqlite_ExcuteSQL Successful,ErrorCode = %d",rv);
	return ret;
}

string CDBConfig::Sqlite_InquireSQL(const char * strSQL)
{
	m_pLog->WriteLog(API_LOG_LEVEL,"Sqlite_InquireSQL:%s",strSQL);
	sqlite3 * pDb = NULL;
	char errMsg[1024] = {0};
	char * pErrMsg = errMsg;
	int ret = -1;

	//数据库打开失败
	if(SQLITE_OK != sqlite3_open(m_pDBName, &pDb))
	{
		m_pLog->WriteLog(API_LOG_LEVEL,"WriteDBConfig:sqlite3_open failure");
		sqlite3_close(pDb);
		return "";
	}

	sqlite3_stmt* stmt = NULL;
	sqlite3_prepare(pDb,strSQL,-1,&stmt,0);

	Json::Value item;
	Json::Value arrayObj;
	char itemValue[409600] = {0};
	while(sqlite3_step(stmt) == SQLITE_ROW)
	{
		//结果中列的总数
		int nCount = sqlite3_column_count(stmt);
		for(int i = 0; i < nCount; i++)
		{
			memset(itemValue,0,409600);
			const unsigned char * pItemValue = sqlite3_column_text(stmt,i);
			if(pItemValue != NULL)
			{
				sprintf(itemValue,"%s",pItemValue);
				item[sqlite3_column_name(stmt,i)] = itemValue;
			}
		}
		arrayObj.append(item);
	}

	sqlite3_finalize(stmt);
	sqlite3_close(pDb);

	string str =  arrayObj.toStyledString();
	//m_pLog->WriteLog(API_LOG_LEVEL,"Sqlite_InquireSQL Successful:%s",str.c_str());
	return str;
}

